package com.robcity.platform.application;

import io.netty.bootstrap.Bootstrap;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioDatagramChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
@Slf4j
@Component
public class Server {
    @Resource
    ServerInitializer serverInitializer;
    @Resource
    WebSocketChannelInitializer webSocketChannelInitializer;
    @Resource
    BootNettyUdpSimpleChannelInboundHandler bootNettyUdpSimpleChannelInboundHandler;

    public  void init() throws InterruptedException {
        //两个事件循环组 boss获取连接发送 worker接收处理
        EventLoopGroup boss = new NioEventLoopGroup();
        EventLoopGroup worker = new NioEventLoopGroup();
        //UDP
        //表示服务器连接监听线程组，专门接受 accept 新的客户端client 连接
        EventLoopGroup bossLoopGroup  = new NioEventLoopGroup();
        try {
            //server启动器
            ServerBootstrap serverWebBootstrap = new ServerBootstrap();
            ServerBootstrap serverRobotBootstrap = new ServerBootstrap();
           //UDP
            //1，创建netty bootstrap 启动类
            Bootstrap serverBootstrap = new Bootstrap();
            // 定义组
            // channel(反射)
            // 定义处理器(自定义)：连接上channel后执行init
            System.out.println("启动server");
            serverRobotBootstrap.group(boss, worker).channel(NioServerSocketChannel.class)
                    .childHandler(serverInitializer);
            serverWebBootstrap.group(boss, worker).channel(NioServerSocketChannel.class)
                    .childHandler(webSocketChannelInitializer);
            //UDP
            //2、设置boostrap 的eventLoopGroup线程组
            serverBootstrap = serverBootstrap.group(bossLoopGroup);
            //3、设置NIO UDP连接通道
            serverBootstrap = serverBootstrap.channel(NioDatagramChannel.class);
            //4、设置通道参数 SO_BROADCAST广播形式
            serverBootstrap = serverBootstrap.option(ChannelOption.SO_BROADCAST, true);
            //5、设置处理类 装配流水线
            serverBootstrap = serverBootstrap.handler(bootNettyUdpSimpleChannelInboundHandler);
            //绑定端口，同步
            ChannelFuture robot = serverRobotBootstrap.bind(8090).sync();
            ChannelFuture web = serverWebBootstrap.bind(8089).sync();

            //6、绑定server，通过调用sync（）方法异步阻塞，直到绑定成功
            ChannelFuture f = serverBootstrap.bind(5002).sync();
            System.out.println(NettyUdpServer.class.getName()+"started and listend on "+f.channel().localAddress());
            //7、监听通道关闭事件，应用程序会一直等待，直到channel关闭
            f.channel().closeFuture().sync();
            robot.channel().closeFuture().sync();
            web.channel().closeFuture().sync();
        } finally {
            boss.shutdownGracefully();
            worker.shutdownGracefully();
        }
    }
}
